package com.yonyou.pmclouds.basecom.util;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.yonyou.pmclouds.basecom.conf.AliTokenProperties;
import com.yonyou.pmclouds.picture.entity.PictureViewVO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.sql.Date;
import java.util.*;

/**
 * oss server端工具类
 *
 * @zhangwce
 */
@Component
public class OssUtil extends AbstractStorageUtil implements InitializingBean {

    private final static long EXPIRE_TIME = 24*60*60;

    @Autowired
    private AliTokenProperties aliTokenProperties;
    private OSSClient client;

    @Override
    public void afterPropertiesSet() throws Exception {
        String endpoint = aliTokenProperties.getEndpoint();
        String accessKeyId = aliTokenProperties.getAccessKeyID();
        String accessKeySecret = aliTokenProperties.getAccessKeySecret();
        ClientConfiguration conf = new ClientConfiguration();
        conf.setProtocol(Protocol.HTTPS);
        client = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
    }

    @Override
    public Map<String, String> getSignWithDir(String dir, HttpServletRequest request) {
        String endpoint = aliTokenProperties.getEndpoint();
        String accessKeyId = aliTokenProperties.getAccessKeyID();
        String bucket = aliTokenProperties.getBucketname();
        String host = "https://" + bucket + "." + endpoint;
        // oss 超时时间限制
        long expireEndTime = System.currentTimeMillis() + EXPIRE_TIME * 1000;
        Date expiration = new Date(expireEndTime);
        PolicyConditions policyConds = new PolicyConditions();
        // oss 文件大小限制
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
        String postPolicy = client.generatePostPolicy(expiration, policyConds);
        byte[] binaryData;
        try {
            binaryData = postPolicy.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Unexpected encoding error. ", e);
        }
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = client.calculatePostSignature(postPolicy);
        Map<String, String> respMap = new LinkedHashMap<>();
        respMap.put("accessKeyId", accessKeyId);
        respMap.put("policy", encodedPolicy);
        respMap.put("signature", postSignature);
        respMap.put("dir", dir);
        respMap.put("host", host);
        respMap.put("expire", String.valueOf(expireEndTime / 1000));

        return respMap;
    }

    @Override
    public String signUrlForSingleAppPic(String pic, String process, HttpServletRequest request) {
        if(StringUtils.isEmpty(pic))
            return "";

        Date expire = new Date(System.currentTimeMillis() + EXPIRE_TIME * 1000);
        GeneratePresignedUrlRequest ossRequest = null;
        if (pic.startsWith("app/") || pic.startsWith("web/")) {
            ossRequest = new GeneratePresignedUrlRequest(aliTokenProperties.getBucketname(), pic);
        } else {
            ossRequest = new GeneratePresignedUrlRequest(aliTokenProperties.getBucketname(), "app/" + pic);
        }
        ossRequest.setExpiration(expire);
        if (StringUtils.isNotEmpty(process))
            ossRequest.setProcess(process);
        URL url = client.generatePresignedUrl(ossRequest);
        return url.toString();
    }

    /**
     * 获取文件内容
     *
     * @param aliTokenProperties, fileNameKey
     * @return long
     * @author yzx
     * @date 2018/7/2 11:12
     */
    @Override
    public long getFileContentLength(String fileNameKey) {
        if (StringUtils.isEmpty(fileNameKey)) {
            return 0;
        }
        String bucketName = aliTokenProperties.getBucketname();
        long fileContentLength = client.getObjectMetadata(bucketName, fileNameKey).getContentLength();
        return fileContentLength;
    }
}
